﻿namespace DimensionsHelper.LanguageService.Syntax;

public interface IDeclaration : ITextNode
{
    /// <summary>
    ///     声明符号名
    /// </summary>
    string Name { get; }


    /// <summary>
    ///     声明符号的名称节点
    /// </summary>
    ITextNode NameIdentifier { get; }


    /// <summary>
    ///     声明使用的关键字Token
    /// </summary>
    ITextNode DeclareKeywordToken { get; }


    /// <summary>
    ///     如果节点是类型签名，返回<see langword="true" />
    /// </summary>
    bool IsSignature { get; }

    /// <summary>
    ///     如果节点是类型签名，包含 Class、Interface 和 Enum，返回<see langword="true" />。
    /// </summary>
    bool IsTypeSignature { get; }


    /// <summary>
    ///     如果声明节点包含指定的修饰符，返回<see langword="true" />
    /// </summary>
    bool ContainsModifier(SyntaxKinds modifierKind);


    /// <summary>
    ///     如果声明节点包含指定的修饰符之一，返回<see langword="true" />
    /// </summary>
    bool ContainsAnyModifier(params SyntaxKinds[] modifiersKinds);
}


public static class DeclarationExtension
{
    public static T? FindParent<T>(this IDeclaration declaration) where T : IDeclaration
    {
        ITextNode? parent = declaration.Parent;

        while (parent != null)
        {
            if (parent.Is<T>(out T? node))
            {
                return node;
            }

            parent = parent.Parent;
        }

        return default;
    }


    /// <summary>
    ///     向上查找包含此节点的<see cref="ModuleSignature" />声明节点。
    /// </summary>
    public static ModuleSignature? FindContainingModule(this IDeclaration declaration)
    {
        return declaration.FindParent<ModuleSignature>();
    }


    /// <summary>
    ///     向上查找包含此节点的类声明节点
    /// </summary>
    public static ClassSignature? FindContainingClass(this IDeclaration declaration)
    {
        return declaration.FindParent<ClassSignature>();
    }


    /// <summary>
    ///     向上查找包含此节点的接口声明节点
    /// </summary>
    public static InterfaceSignature? FindContainingInterface(this IDeclaration declaration)
    {
        return declaration.FindParent<InterfaceSignature>();
    }
}